package org.ehe.finance.voucher.service;

import com.baomidou.mybatisplus.extension.service.IService;
import org.ehe.common.mybatis.core.page.PageQuery;
import org.ehe.common.mybatis.core.page.TableDataInfo;
import org.ehe.finance.voucher.domain.ErpFinanceVoucher;
import org.ehe.finance.voucher.domain.bo.VoucherCreateBo;
import org.ehe.finance.voucher.domain.bo.VoucherQueryBo;
import org.ehe.finance.voucher.domain.bo.VoucherUpdateBo;
import org.ehe.finance.voucher.domain.vo.ErpFinanceVoucherVo;
import org.ehe.finance.voucher.mapper.ErpFinanceVoucherMapper;

import java.time.LocalDate;
import java.util.List;

/**
 * @author :zhangnn
 * @className :ErpFinanceVoucherService
 * @description: TODO
 * @date 2025-08-25 09:35:11
 */
public interface ErpFinanceVoucherService extends IService<ErpFinanceVoucher> {

    /**
     * 分页查询记账凭证
     * @param bo 查询条件
     * @param pageQuery 分页参数
     * @return 分页结果
     */
    TableDataInfo<ErpFinanceVoucherVo> pageVouchers(VoucherQueryBo bo, PageQuery pageQuery);

    /**
     * 创建记账凭证
     * @param createBo 创建对象
     * @return 凭证ID
     */
    Long createVoucher(VoucherCreateBo createBo);

    /**
     * 更新记账凭证
     * @param updateBo 更新对象
     */
    void updateVoucher(VoucherUpdateBo updateBo);

    /**
     * 删除记账凭证
     * @param id 凭证ID
     */
    void deleteVoucher(Long id);

    /**
     * 批量删除记账凭证
     * @param ids 凭证ID列表
     */
    void batchDeleteVouchers(List<Long> ids);

    /**
     * 根据ID获取凭证详情
     * @param id 凭证ID
     * @return 凭证详情
     */
    ErpFinanceVoucherVo getVoucherById(Long id);

    /**
     * 审核凭证
     * @param id 凭证ID
     * @param reviewComment 审核意见
     */
    void reviewVoucher(Long id, String reviewComment);

    /**
     * 反审核凭证
     * @param id 凭证ID
     * @param reason 反审核原因
     */
    void unreviewVoucher(Long id, String reason);

    /**
     * 记账
     * @param id 凭证ID
     */
    void postVoucher(Long id);

    /**
     * 反记账
     * @param id 凭证ID
     * @param reason 反记账原因
     */
    void unpostVoucher(Long id, String reason);

    /**
     * 结账
     * @param ids 凭证ID列表
     */
    void closeVouchers(List<Long> ids);

    /**
     * 反结账
     * @param ids 凭证ID列表
     * @param reason 反结账原因
     */
    void uncloseVouchers(List<Long> ids, String reason);

    /**
     * 批量审核凭证
     * @param ids 凭证ID列表
     * @param reviewComment 审核意见
     */
    void batchReviewVouchers(List<Long> ids, String reviewComment);

    /**
     * 批量记账
     * @param ids 凭证ID列表
     */
    void batchPostVouchers(List<Long> ids);

    /**
     * 检查凭证号是否存在
     * @param voucherNo 凭证号
     * @param excludeId 排除的凭证ID
     * @return 是否存在
     */
    boolean checkVoucherNoExists(String voucherNo, Long excludeId);

    /**
     * 生成凭证号
     * @param voucherTypeId 凭证类别ID
     * @param period 期间
     * @return 凭证号
     */
    String generateVoucherNo(Long voucherTypeId, String period);

    /**
     * 获取下一个凭证号
     * @param voucherTypeId 凭证类别ID
     * @param voucherDate 凭证日期
     * @return 凭证号
     */
    String getNextVoucherNo(Long voucherTypeId, LocalDate voucherDate);

    /**
     * 根据期间获取凭证列表
     * @param period 期间
     * @return 凭证列表
     */
    List<ErpFinanceVoucherVo> getVouchersByPeriod(String period);

    /**
     * 获取期间内凭证状态统计
     * @param period 期间
     * @return 统计结果
     */
    List<ErpFinanceVoucherMapper.VoucherStatusCount> getVoucherStatusCount(String period);

    /**
     * 根据来源单据查询凭证
     * @param sourceId 来源单据ID
     * @param sourceNo 来源单据号
     * @return 凭证列表
     */
    List<ErpFinanceVoucherVo> getVouchersBySource(Long sourceId, String sourceNo);

    /**
     * 复制凭证
     * @param id 源凭证ID
     * @param newVoucherDate 新凭证日期
     * @return 新凭证ID
     */
    Long copyVoucher(Long id, LocalDate newVoucherDate);

    /**
     * 获取用户待审核凭证数量
     * @param userId 用户ID
     * @return 数量
     */
    Long getPendingReviewCount(Long userId);

    /**
     * 验证凭证借贷平衡
     * @param id 凭证ID
     * @return 是否平衡
     */
    boolean validateBalance(Long id);

    /**
     * 更新凭证金额合计
     * @param id 凭证ID
     */
    void updateVoucherTotals(Long id);

    /**
     * 检查期间是否已结账
     * @param period 期间
     * @return 是否已结账
     */
    boolean isPeriodClosed(String period);

    /**
     * 获取凭证打印数据
     * @param id 凭证ID
     * @return 打印数据
     */
    ErpFinanceVoucherVo getVoucherForPrint(Long id);
}
